gh-156112: Load the ObjC runtime by name when find_library() cannot resolve it - #156113
gh-156112: Load the ObjC runtime by name when find_library() cannot resolve it#156113clementperon wants to merge 2 commits into
Conversation
ctypes.util.find_library() resolves a system library through the dyld shared cache, which requires _dyld_shared_cache_contains_path(). Modules/_ctypes/ callproc.c guards that symbol with __builtin_available(iOS 14.0), so on iOS 13 - the oldest release CPython's iOS support targets - find_library() returns None for any library that exists only in the cache, and importing _ios_support fails outright rather than degrading. dyld resolves a bare library name against the cache by itself, so use that when find_library() comes up empty. A genuine load failure is still reported as ImportError.
CPython appends -mios-version-min - the device flag - to every iOS build. Against the simulator SDK the linker rejects the dylibs it resolves there, and the first configure check that links one fails, taking the depends build with it. The local patch faked ac_sys_system=iOS by deleting CPython's host parsing, because config.site.in pinned every package to the tree's darwin triplet. Python now configures against its own iOS triplet, so CPython derives ac_sys_system, the deployment target and the device/simulator split itself, and the 76 lines that deleted that logic are gone. What is left matches three patches under review upstream, so all three can be dropped when python is next bumped: python/cpython#156110 python/cpython#156116 python/cpython#156113 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CPython appends -mios-version-min - the device flag - to every iOS build. Against the simulator SDK the linker rejects the dylibs it resolves there, and the first configure check that links one fails, taking the depends build with it. The local patch faked ac_sys_system=iOS by deleting CPython's host parsing, because config.site.in pinned every package to the tree's darwin triplet. Python now configures against its own iOS triplet, so CPython derives ac_sys_system, the deployment target and the device/simulator split itself, and the 76 lines that deleted that logic are gone. What is left matches three patches under review upstream, so all three can be dropped when python is next bumped: python/cpython#156110 python/cpython#156116 python/cpython#156113 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CPython appends -mios-version-min - the device flag - to every iOS build. Against the simulator SDK the linker rejects the dylibs it resolves there, and the first configure check that links one fails, taking the depends build with it. The local patch faked ac_sys_system=iOS by deleting CPython's host parsing, because config.site.in pinned every package to the tree's darwin triplet. Python now configures against its own iOS triplet, so CPython derives ac_sys_system, the deployment target and the device/simulator split itself, and the 76 lines that deleted that logic are gone. What is left matches three patches under review upstream, so all three can be dropped when python is next bumped: python/cpython#156110 python/cpython#156116 python/cpython#156113 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Is this a problem with an actual reproducible failure mode? If so, what is it? In general, bug fixes are a lot more helpful when they're presented in the context of a reproducible problem. It is then possible to prove that the problem is resolved by applying the patch and testing again. In this case, the proposed solution is that |
|
There is a reproducible case — I should have led with it. Kodi hits this on iOS. Reported by @kambala-decapitator in xbmc/xbmc#28808, tested on iOS 12, 15 and 26 devices: inside an app sandbox the Kodi carries a downstream patch hardcoding On (a): confirmed on main by making the probe raise iOS 12 is below the supported minimum, but iOS 13 is inside it and has the same gap. |
_ios_supportraisesImportErrorat import whenctypes.util.find_library("objc")returnsNone. That happens whenever the dyld shared cache cannot be queried:dyld_find()falls back to_dyld_shared_cache_contains_path(), whichModules/_ctypes/callproc.cguards with__builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *), so on iOS 13 it raisesNotImplementedErrorand no path can be resolved for a library that exists only in the cache.IPHONEOS_DEPLOYMENT_TARGETdefaults to13.0, so this sits inside the supported range, and it takesplatform.platform()andplatform.ios_ver()down with it.dyld resolves a bare library name against the cache by itself, so this falls back to the name when
find_library()comes up empty, and keeps reporting a real load failure asImportErrorrather than lettingOSErrorescape.Verified on macOS, where the same cache mechanism applies —
find_library("objc")names a path that is not a file, and a bare-name load works:and with
find_librarypatched to returnNone, the module loads the runtime andobjc_getClass(b"NSProcessInfo")succeeds.I do not have an iOS 13 device or simulator runtime available, so the import failure itself is derived from the source rather than reproduced on-device; the fallback is verified as above.